#pragma once







/****************************
*          CONTROLS         *
****************************/

static int webcamSetControlCallback_uvc( struct v4l2_ctrl* );

static const struct v4l2_ctrl_ops webcamControlOps_uvc = {
	.s_ctrl = webcamSetControlCallback_uvc,
};


/****************************
*            UVC            *
****************************/

enum {
	UVC_SC_VIDEOCONTROL   = 1,
	UVC_SC_VIDEOSTREAMING = 1,

	UVC_VC_HEADER          = 1,
	UVC_VC_INPUT_TERMINAL  = 2,
	UVC_VC_OUTPUT_TERMINAL = 3,
	UVC_VC_SELECTOR_UNIT   = 4,
	UVC_VC_PROCESSING_UNIT = 5,
	UVC_VC_EXTENSION_UNIT  = 6,

	UVC_VC_REQUEST_ERROR_CODE_CONTROL = 0x02,

	UVC_VS_INPUT_HEADER        = 0x01,
	UVC_VS_FORMAT_UNCOMPRESSED = 0x04,
	UVC_VS_FRAME_UNCOMPRESSED  = 0x05,

	UVC_SET_CUR  = 0x01,
	UVC_GET_CUR  = 0x81,
	UVC_GET_MIN  = 0x82,
	UVC_GET_MAX  = 0x83,
	UVC_GET_RES  = 0x84,
	UVC_GET_LEN  = 0x85,
	UVC_GET_INFO = 0x86,
	UVC_GET_DEF  = 0x87,

	UVC_PU_BACKLIGHT_COMPENSATION_CONTROL = 0x01,
	UVC_PU_BRIGHTNESS_CONTROL             = 0x02,
	UVC_PU_CONTRAST_CONTROL               = 0x03,
	UVC_PU_POWER_LINE_FREQUENCY_CONTROL   = 0x05,
	UVC_PU_HUE_CONTROL                    = 0x06,
	UVC_PU_SATURATION_CONTROL             = 0x07,
	UVC_PU_SHARPNESS_CONTROL              = 0x08,
	UVC_PU_GAMMA_CONTROL                  = 0x09,

	UVC_VS_PROBE_CONTROL  = 0x01,
	UVC_VS_COMMIT_CONTROL = 0x02,

};




static const struct r5u870_uvc_fmtinfo {
	const char* fi_name;
	int         fi_v4l_id;
	u8          fi_guid[16];

} r5u870_uvc_fmts[] = {
	{ .fi_name = "YUY2 4:2:2",
	  .fi_v4l_id = V4L2_PIX_FMT_YUYV,
	  .fi_guid = { 0x59, 0x55, 0x59, 0x32, 0x00, 0x00, 0x10, 0x00,
			   0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } },
	{ }
};


/*
 * Known UVC controls for processing units
 *
 * Not all types of UVC controls are supported.  We stick to simple
 * controls with one or two byte values, and don't do anything very
 * complicated.
 *
 * We don't support camera unit controls, or multiple processing units
 * with instances of the same control.  We also don't check for
 * redefined control IDs, and let usbcam do this for us.
 */

struct r5u870_uvc_ctrlinfo {
	const char*  ci_name;
	u32          ci_v4l_id;
	int          ci_v4l_type;
	int          ci_v4l_flags;
	u8           ci_reg;
	u8           ci_size;
	u8           ci_bm_index;
	int          ci_min, ci_max, ci_def;
	u8           ci_min_force, ci_max_force, ci_def_force;
	const char** ci_menu_names;
	int          ci_val_offset;
};

static struct r5u870_uvc_ctrlinfo r5u870_uvc_proc_ctrls[] = {
	{ .ci_name = "Brightness",
	  .ci_v4l_id = V4L2_CID_BRIGHTNESS,
	  .ci_v4l_type = V4L2_CTRL_TYPE_INTEGER,
	  .ci_v4l_flags = V4L2_CTRL_FLAG_SLIDER,
	  .ci_reg = UVC_PU_BRIGHTNESS_CONTROL,
	  .ci_size = 2,
	  .ci_bm_index = 0 },
	{ .ci_name = "Contrast",
	  .ci_v4l_id = V4L2_CID_CONTRAST,
	  .ci_v4l_type = V4L2_CTRL_TYPE_INTEGER,
	  .ci_v4l_flags = V4L2_CTRL_FLAG_SLIDER,
	  .ci_reg = UVC_PU_CONTRAST_CONTROL,
	  .ci_size = 2,
	  .ci_bm_index = 1 },
	{ .ci_name = "Hue",
	  .ci_v4l_id = V4L2_CID_HUE,
	  .ci_v4l_type = V4L2_CTRL_TYPE_INTEGER,
	  .ci_v4l_flags = V4L2_CTRL_FLAG_SLIDER,
	  .ci_reg = UVC_PU_HUE_CONTROL,
	  .ci_size = 2,
	  .ci_min = -180, .ci_min_force = 1,
	  .ci_max = 180, .ci_max_force = 1,
	  .ci_def = 0, .ci_def_force = 1,
	  .ci_bm_index = 2 },
	{ .ci_name = "Saturation",
	  .ci_v4l_id = V4L2_CID_SATURATION,
	  .ci_v4l_type = V4L2_CTRL_TYPE_INTEGER,
	  .ci_v4l_flags = V4L2_CTRL_FLAG_SLIDER,
	  .ci_reg = UVC_PU_SATURATION_CONTROL,
	  .ci_size = 2,
	  .ci_bm_index = 3 },
	{ .ci_name = "Sharpness",
	  .ci_v4l_id = V4L2_CID_SHARPNESS,
	  .ci_v4l_type = V4L2_CTRL_TYPE_INTEGER,
	  .ci_v4l_flags = V4L2_CTRL_FLAG_SLIDER,
	  .ci_reg = UVC_PU_SHARPNESS_CONTROL,
	  .ci_size = 2,
	  .ci_bm_index = 4 },
	{ .ci_name = "Gamma",
	  .ci_v4l_id = V4L2_CID_GAMMA,
	  .ci_v4l_type = V4L2_CTRL_TYPE_INTEGER,
	  .ci_v4l_flags = V4L2_CTRL_FLAG_SLIDER,
	  .ci_reg = UVC_PU_GAMMA_CONTROL,
	  .ci_size = 2,
	  .ci_bm_index = 5 },
	{ .ci_name = "Backlight Compensation",
	  .ci_v4l_id = V4L2_CID_BACKLIGHT_COMPENSATION,
	  .ci_v4l_type = V4L2_CTRL_TYPE_INTEGER,
	  .ci_v4l_flags = V4L2_CTRL_FLAG_SLIDER,
	  .ci_reg = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
	  .ci_size = 2,
	  .ci_bm_index = 8 },
	{ .ci_name = "Power Line Frequency",
	  .ci_v4l_id = V4L2_CID_POWER_LINE_FREQUENCY,
	  .ci_v4l_type = V4L2_CTRL_TYPE_MENU,
	  .ci_reg = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
	  .ci_size = 1,
	  .ci_bm_index = 10,
	  .ci_min = 0, .ci_min_force = 1,
	  .ci_max = 2, .ci_max_force = 1,
	  .ci_menu_names = powerline_frequency_menu_item_names },
	{ }
};
